With the Framer Motion library, we can render animations in our React app easily.
In this article, we’ll take a look at how to get started with Framer Motion.
Sequencing
The controls.start
method returns a promise so we can use it to sequence animations.
For example, we can write:
import React, { useEffect } from "react";
import { motion, useAnimation } from "framer-motion";
export default function App() {
const controls = useAnimation();
const sequence = async () => {
await controls.start({ x: 0 });
return await controls.start({ opacity: 1 });
};
useEffect(() => {
sequence();
}, []);
return (
<motion.div
animate={controls}
style={{ backgroundColor: "red", width: 100, height: 100 }}
/>
);
}
We have the sequence
function that calls controls.start
with different styles.
So this is what we’ll see when we load our component.
Dynamic Start
We can call controls.start
dynamically.
For example, we can write:
import React, { useEffect } from "react";
import { motion, useAnimation } from "framer-motion";
export default function App() {
const controls = useAnimation();
useEffect(() => {
controls.start((i) => ({
opacity: 0,
x: 100,
transition: { delay: i * 0.3 }
}));
}, []);
return (
<ul>
<motion.li custom={0} animate={controls}>
foo
</motion.li>
<motion.li custom={1} animate={controls}>
bar
</motion.li>
<motion.li custom={2} animate={controls}>
baz
</motion.li>
</ul>
);
}
We pass in a callback with the i
parameter, which is the value that we passed into the custom
prop.
And we pass into the animate
prop to set the controls
to control the animation.
Layout Animations
We can animate layouts with Framer Motion
For example, we can write:
App.js
import React, { useState } from "react";
import { motion } from "framer-motion";
import "./styles.css";
const spring = {
type: "spring",
stiffness: 700,
damping: 30
};
export default function App() {
const [isOn, setIsOn] = useState(false);
const toggleSwitch = () => setIsOn(!isOn);
return (
<div className="switch" data-isOn={isOn} onClick={toggleSwitch}>
<motion.div className="handle" layout transition={spring} />
</div>
);
}
styles.css
html,
body {
min-height: 100vh;
padding: 0;
margin: 0;
}
* {
box-sizing: border-box;
}
.App {
font-family: sans-serif;
text-align: center;
}
.switch {
width: 160px;
height: 100px;
background-color: green;
display: flex;
justify-content: flex-start;
border-radius: 50px;
padding: 10px;
cursor: pointer;
}
.switch[data-isOn="true"] {
justify-content: flex-end;
}
.handle {
width: 80px;
height: 80px;
background-color: white;
border-radius: 40px;
}
We add the spring
animation effect and pass that into the transition
prop.
The onClick
prop has the function to control the isOn
state.
The layout
prop lets us animate the layout of the div.
We add the styles to style our div into a switch.
justify-content
set to flex-start
has the switch bottom on the left. and flex-end
puts the switch button to the right.
Conclusion
We can control our animation progress with Framer Motion.
And we can apply animations for layouts.